#include "GraphicsDrawingItem.h"
#include <DrawCommand.h>
#include <GraphicsUtil.h>
#include <GraphicsScene.h>
#include <GraphicsView.h>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QGraphicsColorizeEffect>
#include <QFile>
#include <QCursor>
#include <QDebug>

GraphicsDrawingItem::GraphicsDrawingItem(GraphicsBaseItem* parent, GraphicsScene* scene)
	:GraphicsBaseItem(GraphicsItemType::Drawing_Enum, scene, parent)
{
	// 子图元不超出显示
	setFlag(QGraphicsItem::ItemClipsChildrenToShape);
	GraphicsView* view = getScene()->getView();
	if (view) {
		connect(view, &GraphicsView::sigViewScaleChanged, [=] {
			setCursor(getCursor());
			});
	}
	setCursor(getCursor());
	connect(&m_data, &GraphicsBaseItemData::sigItemScaleChanged, this, &GraphicsDrawingItem::onUpdateMask);
	connect(&m_data, &GraphicsBaseItemData::sigSizeChanged, this, &GraphicsDrawingItem::onUpdateMask);
	createBackgroundImage();
}

void GraphicsDrawingItem::setImage(const QImage& sourceImage)
{
	if (m_scene)
		m_scene->clearUndoStack();
	m_image = sourceImage;
	const qreal aspectRatio = (qreal)m_image.width() / (qreal)m_image.height();
	m_data.setDefaultSize(QSize(m_image.width(), m_image.height()));
	m_data.setBaseItemAspectRatio(aspectRatio);
	m_data.setOriginImage(sourceImage);
	update();
}

void GraphicsDrawingItem::fitToScreen()
{
	assert(m_scene);
	assert(m_scene->getView());
	const QSize viewSize = getScene()->getView()->size() * 0.9;
	setSize(viewSize);
	m_scene->getView()->centerOn(this);
}

void GraphicsDrawingItem::setSize(const QSize& size)
{
	const qreal aspectRatio = m_data.getBaseItemAspectRatio();
	QSizeF keepRatioSize = GraphicsUtil::getKeepRatioSize(size.width(), size.height(), aspectRatio);
	getItemData().setScaleSize(keepRatioSize);
	if (m_scene && m_scene->getView())
		emit m_scene->getView()->sigViewScaleChanged();
}

void GraphicsDrawingItem::setMaskImage(const QImage& maskImage)
{
	m_maskImage = maskImage;
	onUpdateMask();
}

void GraphicsDrawingItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
{
	QSizeF scaleSize = getItemData().getScaleSize();
	if (scaleSize.width() < 0 || scaleSize.height() < 0)
		return;

	if (m_image.isNull())
		return;

	// 绘制背景图片
	painter->drawImage(QPointF(-scaleSize.width() / 2, -scaleSize.height() / 2), m_bcImage, QRect(QPoint(0, 0), scaleSize.toSize()));

	// 绘制前景图片
	QImage scaleImage = m_image.scaled(scaleSize.toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
	painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
	painter->drawImage(QPointF(-scaleSize.width() / 2, -scaleSize.height() / 2), scaleImage);

	// 绘制遮罩
	if (m_isVisableMask) {
		const QImage mask = getItemData().getMaskImage();
		if (!mask.isNull()) {
			painter->drawImage(QPointF(-scaleSize.width() / 2, -scaleSize.height() / 2), mask);
		}
	}

	painter->drawRect(QRectF(QPointF(-scaleSize.width() / 2, -scaleSize.height() / 2), scaleSize));

	// 显示画笔
	if (m_isVisablePen)
	{
		QPixmap pixmap = getCursor().pixmap();
		painter->drawPixmap(QPointF(-pixmap.width() / 2, -pixmap.height() / 2), pixmap);
	}
}

void GraphicsDrawingItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
	const QImage mask = getItemData().getMaskImage();
	m_pressMask = mask;
	m_pressPoint = event->pos();
	if (mask.isNull()) {
		QImage image = QImage(getItemData().getScaleSize().toSize(), QImage::Format_RGBA8888);
		image.fill(Qt::transparent);
		getItemData().setMaskImage(image);
	}

	m_isPressed = true;
	m_penPath.clear();
	m_penPath.moveTo(event->pos());
	GraphicsBaseItem::mousePressEvent(event);
}

void GraphicsDrawingItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
	QSizeF scaleSize = getItemData().getScaleSize();
	if (m_isPressed) {
		QImage mask = getItemData().getMaskImage();
		m_penPath.lineTo(event->pos());
		QPainter painter(&mask);
		painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
		painter.setOpacity(250.0 / 255.0);
		painter.translate(scaleSize.width() / 2, scaleSize.height() / 2);
		QPainterPath painterPath = strokerPath(m_penPath);
		if (m_type == DrawingType::Pen) {
			// 画笔
			painter.setCompositionMode(QPainter::CompositionMode_Source);
			painter.fillPath(painterPath, QBrush(m_penColor));
		}
		else {
			// 橡皮檫
			painter.setCompositionMode(QPainter::CompositionMode_Clear);
			painter.fillPath(painterPath, QBrush(Qt::transparent));
		}
		getItemData().setMaskImage(mask);
		update();
	}
	GraphicsBaseItem::mouseMoveEvent(event);
}

void GraphicsDrawingItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
	const QImage mask = getItemData().getMaskImage();
	m_isPressed = false;
	if (m_pressPoint != event->pos()) {
		DrawCommand* drawCommand = new DrawCommand(this, m_pressMask, mask);
		m_scene->pushCommand(drawCommand);
		getItemData().setMaskImage(mask);
	}
	GraphicsBaseItem::mouseReleaseEvent(event);
}

void GraphicsDrawingItem::createBackgroundImage()
{
	QImage image(":/images/aiexpandbackground.png");
	const int width = image.width();
	const int height = image.height();

	// 背景图拼接
	QImage bigImage(width * 4, height * 4, QImage::Format_ARGB32_Premultiplied);
	QPainter painter(&bigImage);
	painter.setCompositionMode(QPainter::CompositionMode_Source);
	painter.fillRect(QRect(0, 0, width * 4, height * 4), Qt::transparent);
	for (int i(0); i < 4; ++i) {
		for (int j(0); j < 4; ++j) {
			painter.drawImage(width * i, height * j, image);
		}
	}
	painter.end();
	m_bcImage = bigImage;
}

void GraphicsDrawingItem::onUpdateMask()
{
	if (m_maskImage.isNull())
		return;

	/*if (!getItemData().getMaskImage().isNull())
		return;*/

	QSizeF scaleSize = getItemData().getScaleSize();
	QImage image = m_maskImage.scaled(scaleSize.toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
	// 将alpha不为0的像素点替换为m_penColor
	for (int y = 0; y < image.height(); ++y) {
		for (int x = 0; x < image.width(); ++x) {
			QColor color = image.pixelColor(x, y);
			if (color.alpha() != 0) {
				image.setPixel(x, y, m_penColor.rgba());
			}
		}
	}
	getItemData().setMaskImage(image);
}

QPainterPath GraphicsDrawingItem::strokerPath(QPainterPath& path)
{
	QPainterPathStroker stroker;
	stroker.setCapStyle(Qt::RoundCap);  // 端点风格
	stroker.setJoinStyle(Qt::RoundJoin);  // 连接样式
	stroker.setDashPattern(Qt::SolidLine);  // 虚线图案
	stroker.setWidth(m_penWidth);  // 宽度

	QPainterPath painterPath = stroker.createStroke(path);
	painterPath.setFillRule(Qt::WindingFill);
	// 生成一个新路径（可填充区域），表示原始路径 path 的轮廓
	return painterPath;
}

QCursor GraphicsDrawingItem::getCursor()
{
	GraphicsView* view = getScene()->getView();
	const qreal viewScale = view->getViewScale();

	int penWidth = m_penWidth * viewScale;
	if (penWidth < 2) {
		penWidth = 2;
	}
	QImage image(QSize(penWidth, penWidth), QImage::Format_RGBA8888);
	image.fill(Qt::transparent);
	QPainter painter(&image);
	painter.setPen(QPen(Qt::white, 1));
	painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
	painter.drawEllipse(QPoint(penWidth / 2, penWidth / 2), penWidth / 2, penWidth / 2);

	QCursor cursor(QPixmap::fromImage(image));
	return cursor;
}

void GraphicsDrawingItem::init()
{
	moveToParentCenter();
	m_scene->setCenterItem(this);
}

void GraphicsDrawingItem::initGraphics()
{
	// 设置以图元为中心
	setOriginOnCenter();
	init();
}

void GraphicsDrawingItem::setDrawingType(DrawingType type)
{
	m_type = type;
}

void GraphicsDrawingItem::setPenWidth(qreal penWidth)
{
	m_penWidth = penWidth;
	// 设置鼠标大小
	setCursor(getCursor());
	update();
}

void GraphicsDrawingItem::setPenVisable(bool isVisable)
{
	m_isVisablePen = isVisable;
	update();
}

void GraphicsDrawingItem::setMaskVisable(bool isVisable)
{
	m_isVisableMask = isVisable;
	update();
}
